home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Listing 2
-
- outlist.cpp--Print out a "calling tree."
-
- Compiler: Borland C++ 2.0.
- Library: SoftC version 2.1f or 3.0.
-
- 17 March 1992, by Mark W. Schumann
- Usenet: mark@whizbang.ncoast.org
-
- Compile (Borland) with:
-
- bcc -ms -lm outlist.cpp scdbp20s.lib
-
- This program uses a C++ string class originally
- developed by John Bernstein (CIS 70244,1237).
-
- You can probably substitute any of the usual
- C++ implementations of strings without too
- much trouble.
-
- -------------------------------------------------
-
- OUTLIST-- Print out a "calling tree."
- Copyright (C) 1992 by Mark W. Schumann
-
- This program is distributed in the hope that
- it will be useful, but WITHOUT ANY WARRANTY;
- without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE.
-
- */
-
- #include <softc.h>
- #include <sc_base.h>
-
- #include <ctype.h>
- #include <dir.h>
- #include <iostream.h>
- #include <string.h>
-
- #include "oostring.h" // Bernstein's class header.
-
- int dbf = -1; // Handle of CALLTREE.DBF.
- int ntx1 = -1; // ...of MEMBER.NTX.
- int ntx2 = -1; // ...of CALLEDBY.NTX.
-
- SC_DBFRINFO rinfo;
- SC_FIELD *finfo = NULL;
-
- int f_member; // Field handles for MEMBER,
- int f_calledby; // CALLEDBY, PHONE, and NAME
- int f_phone; // fields in CALLTREE file.
- int f_name;
-
- // Given member/level, print callees.
- int printtree (char *, int);
-
- // Short-compare of strings.
- int sstrcmp (char const *, char const *);
-
- // Does file exist?
- int file (char const *);
-
- // Check for SoftC error and get out.
- void errcheck (char const *);
-
- // Deallocation and file closes.
- void cleanup (void);
-
- // Return .TRUE. if null string.
- int nil (const char *);
-
- // Return .TRUE. if all whitespace.
- int empty (const char *);
-
-
- //
- // Open CALLTREE with MEMBER and CALLEDBY indexes.
- // Then just call printlist() with the
- // command-line arg.
- //
-
- int main (int argc, char *argv[])
-
- {
-
- int flong;
-
- atexit (cleanup);
-
- scdinit (20, 0);
-
- scddopenx (&dbf, "CALLTREE.DBF", SC_RDONLY);
- errcheck ("Opening CALLTREE.DBF");
- scddrinfo (dbf, &rinfo);
- finfo = new SC_FIELD [rinfo.numflds];
- scddfinfo (dbf, &flong, finfo);
- scddfnam2no (dbf, &f_member, "MEMBER");
- scddfnam2no (dbf, &f_calledby, "CALLEDBY");
- scddfnam2no (dbf, &f_phone, "PHONE");
- scddfnam2no (dbf, &f_name, "NAME");
-
- if (!file ("MEMBER.NTX")) {
-
- long lRec;
- char buffer[7];
-
- scdccreate ("MEMBER.NTX", SC_CKEY | SC_UNIQUE,
- "MEMBER", 3, 0);
- scdcopenx (&ntx1, "MEMBER.NTX",
- SC_RDWR | SC_EXCLUDE | SC_BUFFER);
- cout << "Indexing on MEMBER...\n";
-
- for (lRec = 1L; ; lRec++) {
- if (scddrget (dbf, lRec) == SC_SKFAIL) {
- sceclr();
- break;
- }
- errcheck ("Indexing on MEMBER.");
- scddfgets (dbf, 0, buffer);
- scdckadd (ntx1, buffer, lRec);
- cout << '\r' << lRec << " records indexed";
- }
-
- cout << '\n';
- scdcclose (ntx1);
- }
-
- scdcopenx (&ntx1, "MEMBER.NTX", SC_RDONLY);
- errcheck ("Opening MEMBER.NTX");
-
-
- if (!file ("CALLEDBY.NTX")) {
-
- long lRec;
- char buffer[7];
-
- scdccreate ("CALLEDBY.NTX",
- SC_CKEY | SC_UNIQUE,
- "CALLEDBY+MEMBER", 6, 0);
-
- scdcopenx (&ntx2, "CALLEDBY.NTX",
- SC_RDWR | SC_EXCLUDE | SC_BUFFER);
-
- cout << "Indexing on CALLEDBY+MEMBER...\n";
-
- for (lRec = 1L; ; lRec++) {
- if (scddrget (dbf, lRec) == SC_SKFAIL) {
- sceclr();
- break;
- }
- errcheck ("Indexing on CALLEDBY+MEMBER.");
- scddfgets (dbf, f_calledby, buffer);
- scddfgets (dbf, f_member,
- buffer + finfo[f_calledby].len);
- scdckadd (ntx2, buffer, lRec);
- cout << '\r' << lRec << " records indexed";
- }
-
- cout << '\n';
- scdcclose (ntx2);
- }
-
- scdcopenx (&ntx2, "CALLEDBY.NTX", SC_RDONLY);
- errcheck ("Opening CALLEDBY.NTX");
- printtree (argc > 1 ? argv[1] : "", 0);
-
- }
-
-
- //
- // printtree (char *cpFr, int npLv);
- //
- // Recursively print out all people called by "cpFr."
- //
- // Parameters:
- //
- // cpFr ASCIIZ string indicating caller's number.
- // npLv Indicates "level" of output.
- //
-
- int printtree (char *cpFr, int npLv)
-
- {
-
- char member[4]; // Assume DBF: MEMBER C 3
- char calledby[4]; // CALLEDBY C 3
- char phone[8]; // PHONE C 7
- char name[31]; // NAME C 30
-
- char keybuffer[50]; // Buffer for key values, natch.
- long nRec; // Current record number.
- int nScCd; // SoftC error code.
- register int i;
-
- sceclr();
-
- strcpy (keybuffer, cpFr);
-
- nScCd = scdckfind (
- ntx2,
- (void *) keybuffer,
- &nRec,
- SC_FIRST);
-
- // The index now points to the first matching
- // record, if any. Now read in sequence until
- // there is a non-matching record. Exit on
- // error (code < 0) or end-of-file (code == SC_END).
-
- while (nScCd >= 0 && nScCd != SC_END) {
-
- // Get a record and ensure a match.
- scddrget (dbf, nRec);
- scddfgets (dbf, f_calledby, calledby);
-
- if (nil (cpFr) ? !empty (calledby)
- : sstrcmp (calledby, cpFr))
- break;
-
- // Break record into fields.
- scddfgets (dbf, f_member, member);
- scddfgets (dbf, f_name, name);
- scddfgets (dbf, f_phone, phone);
-
- for (i = 0; i < npLv; i++) cout << '\t';
-
- cout << trim (name);
-
- if (!empty (phone))
- cout << " (" + substr (phone, 0, 3) + ;
- "-" + substr (phone, 3) + ")";
- cout << '\n';
-
- // This recursive call changes the index
- // pointer information:
- printtree (member, npLv + 1);
-
- // Now to fix index pointer:
- nScCd = scdckfind (
- ntx2,
- (void *) keybuffer,
- &nRec,
- SC_EXACT);
-
- // And go to the next record. This
- // won't work in the case of duplicate
- // keys, by the way.
- if (nScCd >= 0)
- nScCd = scdcknext (
- ntx2,
- (void *) keybuffer,
- &nRec);
-
- }
-
- errcheck ("Printing call list");
- return nScCd;
-
- }
-
-
- //---------- Minor support functions ----------//
-
- int sstrcmp (char const *a, char const *b)
-
- {
-
- register int i;
-
- for (i = 0; a[i] && b[i]; i++)
- if (a[i] != b[i]) return (a[i] - b[i]);
-
- return 0;
-
- }
-
- int file (const char *cName)
-
- {
-
- struct ffblk ff;
-
- return (!findfirst (cName, &ff, 0));
-
- }
-
- void errcheck (char const *cText)
-
- {
-
- if (sc_code < 0) {
- cout << "SoftC error " << sc_code << '\n';
- cout << scemsg() << '\n';
- cout << cText;
- exit (-1);
- }
- }
-
- void cleanup (void)
-
- {
-
- scddclose (dbf);
- scdcclose (ntx1);
- scdcclose (ntx2);
-
- if (finfo != NULL)
- delete finfo;
-
- scdterm();
-
- }
-
- int nil (const char *s)
-
- {
-
- return (s[0] == '\0');
-
- }
-
- int empty (const char *s)
-
- {
-
- register int i;
-
- for (i = 0; s[i]; i++)
- if (!isspace (s[i])) return 0;
-
- return 1;
-
- }
-
- --
- Mark W. Schumann/3111 Mapledale Avenue/Cleveland, Ohio 44109-2447 USA
- Domain: mark@whizbang.wariat.org CIS: 73750,3527
- "Now when I tell people I'm Slovak, they won't think I'm Czech."
- --My wife Judy (Mravetz) Schumann remarking upon the Czech/Slovak split
-
-